package com.genexususa.eo.bing.connection;

import com.genexususa.eo.bing.CampaignManagementServiceClasses.*;
import com.genexususa.eo.bing.data.GxException;
import com.genexususa.eo.bing.data.Info;
import com.genexususa.eo.bing.data.Util;
import com.genexususa.eo.bing.data.wsSubclasses.*;
import com.genexususa.eo.google.data.GA_Result;
import com.genexususa.eo.google.data.GA_ResultItem;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import java.io.StringWriter;
import java.rmi.RemoteException;
import java.util.HashMap;

public class AdExtensionManager {
    public AdExtensionManager() {
    }

    public String addAdExtensions(long customerAccountId, String adExtensionsXML) {
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        AddAdExtensionsRequest addAdExtensionsRequest = null;
        AddAdExtensionsResponse addAdExtensionsResponse = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        AdExtension[] adExtensions = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");


            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            addAdExtensionsRequest = new AddAdExtensionsRequest();
            addAdExtensionsRequest.setAccountId(customerAccountId);
            // Parse adExtensions from XML
            adExtensions = util.adExtensionsFromXML(adExtensionsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            //addAdExtensionsRequest.setAdExtensions(adExtensions);


            AdExtension[] allAdExtensions = adExtensions;
            AdExtension[] chunkedAdExtension = null;
            // max element limit = 1000
            int chunks = (int)Math.ceil(allAdExtensions.length / 1000.0);
            if (chunks <= 1){
                addAdExtensionsRequest.setAdExtensions(allAdExtensions);

                addAdExtensionsResponse = campaignManagement.addAdExtensions(addAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

                AdExtensionIdentity[] adExtensionIdentities = addAdExtensionsResponse.getAdExtensionIdentities();
                for (int i=0; i<adExtensionIdentities.length; i++) {
                    GA_ResultItem resultItem = new GA_ResultItem();
                    if (adExtensions[i] instanceof CallAdExtension) {

                        resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                        resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else if (adExtensions[i] instanceof GxProductAdExtension) {
                        resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else {
                        resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    }

                    result.Items.add(resultItem);
                }

            }else if(chunks > 1){
                int counter = 1;
                int index = 0;
                int chunkItems = 1000;
                while (counter <= chunks){
                    if(counter == chunks){
                        chunkItems = allAdExtensions.length - index;
                    }

                    chunkedAdExtension = new AdExtension[chunkItems];
                    for(int i = 0; i < chunkItems ; i++){
                        chunkedAdExtension[i] = allAdExtensions[index];
                        index+=1;
                    }
                    index = counter * 1000;
                    counter++;

                    addAdExtensionsRequest.setAdExtensions(chunkedAdExtension);

                    addAdExtensionsResponse = campaignManagement.addAdExtensions(addAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

                    AdExtensionIdentity[] adExtensionIdentities = addAdExtensionsResponse.getAdExtensionIdentities();

                    //result = new GxVersionResults(trackingId, adExtensionIdentities.length);
                    for (int i=0; i<adExtensionIdentities.length; i++) {
                        GA_ResultItem resultItem = new GA_ResultItem();

                        if (adExtensions[i] instanceof CallAdExtension) {

                            resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                            resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else if (adExtensions[i] instanceof GxProductAdExtension) {
                            resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else {
                            resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensionIdentities[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        }

                        result.Items.add(resultItem);
                    }

                }
            }


            // Call WS
            //addAdExtensionsResponse = campaignManagement.addAdExtensions(addAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            /*trackingId = stub.getResponseHeader(namespace, "TrackingId").getValue();
            AdExtensionIdentity[] adExtensionIdentities = addAdExtensionsResponse.getAdExtensionIdentities();
            result = new GxVersionResults(trackingId, adExtensionIdentities.length);
            for (int i=0; i<adExtensionIdentities.length; i++) {
                if (adExtensions[i] instanceof CallAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else {
                    result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                }
            }
            */
        } catch (GxException e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        } catch (EditorialApiFaultDetail fault) { // IN CALL
            for (int i=0; i< adExtensions.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                if (adExtensions[i] instanceof GxCallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxCallAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxLocationAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxProductAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxSiteLinksAdExtension) {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (ApiFaultDetail fault) { // IN CALL
            for (int i=0; i<addAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                if (addAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<addAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault);

                if (addAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<addAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(e);

                if (addAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)addAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }
                result.Items.add(resultItem);
            }
        } catch (Exception e) { // BEFORE CALL
            e.printStackTrace();
            result.Items.add(new GA_ResultItem(e));
        }

        String returnMessage = null;
        // GxVersionResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    public String updateAdExtensions(long customerAccountId, String adExtensionsXML) {
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        UpdateAdExtensionsRequest updateAdExtensionsRequest = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        AdExtension[] adExtensions = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            updateAdExtensionsRequest = new UpdateAdExtensionsRequest();
            updateAdExtensionsRequest.setAccountId(customerAccountId);
            // Parse adExtensions from XML
            adExtensions = util.adExtensionsFromXML(adExtensionsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            //updateAdExtensionsRequest.setAdExtensions(adExtensions);

            AdExtension[] allAdExtensions = adExtensions;
            AdExtension[] chunkedAdExtension = null;
            // max element limit = 1000
            int chunks = (int)Math.ceil(allAdExtensions.length / 1000.0);
            if (chunks <= 1){
                updateAdExtensionsRequest.setAdExtensions(allAdExtensions);

                campaignManagement.updateAdExtensions(updateAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

                //result = new GxVersionResults(trackingId, adExtensionIdentities.length);
                for (int i=0; i<updateAdExtensionsRequest.getAdExtensions().length; i++) {
                    GA_ResultItem resultItem = new GA_ResultItem();
                    if (adExtensions[i] instanceof CallAdExtension) {
                        resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensions[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                        resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensions[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else if (adExtensions[i] instanceof GxProductAdExtension) {
                        resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensions[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    } else {
                        resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                        resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                        resultItem.AdExtensionId = adExtensions[i].getId();

                        //result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                    }

                    result.Items.add(resultItem);
                }

            } else if(chunks > 1) {
                int counter = 1;
                int index = 0;
                int chunkItems = 1000;
                while (counter <= chunks){
                    if(counter == chunks){
                        chunkItems = allAdExtensions.length - index;
                    }

                    chunkedAdExtension = new AdExtension[chunkItems];
                    for(int i = 0; i < chunkItems ; i++){
                        chunkedAdExtension[i] = allAdExtensions[index];
                        index+=1;
                    }
                    index = counter * 1000;
                    counter++;

                    updateAdExtensionsRequest.setAdExtensions(chunkedAdExtension);

                    campaignManagement.updateAdExtensions(updateAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

                    //result = new GxVersionResults(trackingId, adExtensionIdentities.length);
                    for (int i=0; i<updateAdExtensionsRequest.getAdExtensions().length; i++) {
                        GA_ResultItem resultItem = new GA_ResultItem();

                        if (adExtensions[i] instanceof CallAdExtension) {

                            resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensions[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                            resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensions[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else if (adExtensions[i] instanceof GxProductAdExtension) {
                            resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensions[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        } else {
                            resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                            resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                            resultItem.AdExtensionId = adExtensions[i].getId();

                            //result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                        }

                        result.Items.add(resultItem);
                    }

                }
            }


            // Call WS
            //updateAdExtensionsResponse = campaignManagement.updateAdExtensions(updateAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            /*trackingId = stub.getResponseHeader(namespace, "TrackingId").getValue();
            AdExtensionIdentity[] adExtensionIdentities = updateAdExtensionsResponse.getAdExtensionIdentities();
            result = new GxVersionResults(trackingId, adExtensionIdentities.length);
            for (int i=0; i<adExtensionIdentities.length; i++) {
                if (adExtensions[i] instanceof CallAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxCallAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxLocationAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    result.addResult(i, new GxVersionResult(((GxProductAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                } else {
                    result.addResult(i, new GxVersionResult(((GxSiteLinksAdExtension)adExtensions[i]).getGxId(), adExtensionIdentities[i].getId(), adExtensionIdentities[i].getVersion()));
                }
            }
            */
        } catch (GxException e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        } catch (EditorialApiFaultDetail fault) { // IN CALL
            for (int i=0; i< adExtensions.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                if (adExtensions[i] instanceof GxCallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxCallAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxLocationAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxProductAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxSiteLinksAdExtension) {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId= ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (ApiFaultDetail fault) { // IN CALL
            for (int i=0; i<updateAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                if (updateAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<updateAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault);

                if (updateAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }
                result.Items.add(resultItem);
            }
        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<updateAdExtensionsRequest.getAdExtensions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(e);

                if (updateAdExtensionsRequest.getAdExtensions()[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)updateAdExtensionsRequest.getAdExtensions()[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (Exception e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        }

        String returnMessage = null;
        // GxVersionResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    public String setAdExtensionsToCampaigns(long customerAccountId, String adExtensionIdToCampaignIdAssociationsXML) {
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        //SetAdExtensionsToCampaignsRequest setAdExtensionsToCampaignsRequest = null;
        SetAdExtensionsAssociationsRequest setAdExtensionsAssociationsRequest = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        //AdExtensionIdToCampaignIdAssociation[] adExtensionIdToCampaignIdAssociations = null;
        GxAdExtensionIdToCampaignIdAssociation[] adExtensionIdToCampaignIdAssociations = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            //setAdExtensionsToCampaignsRequest = new SetAdExtensionsToCampaignsRequest();
            //setAdExtensionsToCampaignsRequest.setAccountId(accountId);
            // Parse adExtensionIdToCampaignIdAssociations from XML
            //adExtensionIdToCampaignIdAssociations = util.adExtensionIdToCampaignIdAssociationsFromXML(adExtensionIdToCampaignIdAssociationsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            //setAdExtensionsToCampaignsRequest.setAdExtensionIdToCampaignIdAssociations(adExtensionIdToCampaignIdAssociations);

            setAdExtensionsAssociationsRequest = new SetAdExtensionsAssociationsRequest();
            setAdExtensionsAssociationsRequest.setAccountId(customerAccountId);
            adExtensionIdToCampaignIdAssociations = util.adExtensionIdToCampaignIdAssociationsFromXML(adExtensionIdToCampaignIdAssociationsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            setAdExtensionsAssociationsRequest.setAdExtensionIdToEntityIdAssociations(adExtensionIdToCampaignIdAssociations);
            setAdExtensionsAssociationsRequest.setAssociationType(AssociationType.Campaign);

            // Call WS
            //campaignManagement.setAdExtensionsToCampaigns(setAdExtensionsToCampaignsRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail
            campaignManagement.setAdExtensionsAssociations(setAdExtensionsAssociationsRequest);
            // Call succeeded with no errors

            // Create the return object
            //result = new GxAdExtensionIdCampaignIdResults(trackingId, adExtensionIdToCampaignIdAssociations.length);
            for (int i=0; i<adExtensionIdToCampaignIdAssociations.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();
                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxCampaignId();
                resultItem.AdExtensionId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId();
                resultItem.CampaignId =  adExtensionIdToCampaignIdAssociations[i].getEntityId();

                result.Items.add(resultItem);
                //result.addResult(i, new GxAdExtensionIdCampaignIdResult(((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId(), ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxCampaignId(), adExtensionIdToCampaignIdAssociations[i].getAdExtensionId(), adExtensionIdToCampaignIdAssociations[i].getEntityId()));
            }
        } catch (GxException e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        } catch (EditorialApiFaultDetail fault) { // IN CALL
            for (int i=0; i< setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);
                resultItem.SubCampaignGxId = adExtensionIdToCampaignIdAssociations[i].getGxCampaignId();
                resultItem.AdExtensionGxId= adExtensionIdToCampaignIdAssociations[i].getGxAdExtensionId();

                result.Items.add(resultItem);
            }
        } catch (ApiFaultDetail fault) { // IN CALL
            for (int i=0; i<setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(e);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) setAdExtensionsAssociationsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (Exception e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        }

        String returnMessage = null;
        // GxAdExtensionIdCampaignIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    public String deleteAdExtensions(long customerAccountId, String adExtensionsXML) {
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        DeleteAdExtensionsRequest deleteAdExtensionsRequest = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        AdExtension[] adExtensions = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            deleteAdExtensionsRequest = new DeleteAdExtensionsRequest();
            deleteAdExtensionsRequest.setAccountId(customerAccountId);
            // Parse adExtensions from XML
            adExtensions = util.adExtensionsFromXML(adExtensionsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            long[] adExtensionIds = new long[adExtensions.length];
            for (int i=0; i<adExtensionIds.length; i++) {
                if (adExtensions[i].getId() == null) {
                    adExtensionIds[i] = -1;
                } else {
                    adExtensionIds[i] = adExtensions[i].getId();
                }
            }
            deleteAdExtensionsRequest.setAdExtensionIds(adExtensionIds);

            // Call WS
            campaignManagement.deleteAdExtensions(deleteAdExtensionsRequest); // RemoteException, EditorialApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            for (int i=0; i<adExtensionIds.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();
                if (adExtensions[i] instanceof GxCallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension) adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension) adExtensions[i]).getGxId();
                    resultItem.AdExtensionId = adExtensionIds[i];

                    //result.addResult(i, new GxIdResult(((GxCallAdExtension) adExtensions[i]).getGxId(), adExtensionIds[i]));
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension) adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension) adExtensions[i]).getGxId();
                    resultItem.AdExtensionId = adExtensionIds[i];

                    //result.addResult(i, new GxIdResult(((GxLocationAdExtension) adExtensions[i]).getGxId(), adExtensionIds[i]));
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension) adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension) adExtensions[i]).getGxId();
                    resultItem.AdExtensionId = adExtensionIds[i];

                    //result.addResult(i, new GxIdResult(((GxProductAdExtension) adExtensions[i]).getGxId(), adExtensionIds[i]));
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension) adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension) adExtensions[i]).getGxId();
                    resultItem.AdExtensionId = adExtensionIds[i];

                    //result.addResult(i, new GxIdResult(((GxSiteLinksAdExtension) adExtensions[i]).getGxId(), adExtensionIds[i]));
                }

                result.Items.add(resultItem);
            }
        } catch (GxException e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        } catch (ApiFaultDetail fault) { // IN CALL
            for (int i=0; i<deleteAdExtensionsRequest.getAdExtensionIds().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                if (adExtensions[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<deleteAdExtensionsRequest.getAdExtensionIds().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault);

                if (adExtensions[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<deleteAdExtensionsRequest.getAdExtensionIds().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(e);

                if (adExtensions[i] instanceof CallAdExtension) {
                    resultItem.SubCampaignGxId = ((GxCallAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxCallAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxLocationAdExtension) {
                    resultItem.SubCampaignGxId = ((GxLocationAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxLocationAdExtension)adExtensions[i]).getGxId();
                } else if (adExtensions[i] instanceof GxProductAdExtension) {
                    resultItem.SubCampaignGxId = ((GxProductAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxProductAdExtension)adExtensions[i]).getGxId();
                } else {
                    resultItem.SubCampaignGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxCampaignId();
                    resultItem.AdExtensionGxId = ((GxSiteLinksAdExtension)adExtensions[i]).getGxId();
                }

                result.Items.add(resultItem);
            }
        } catch (Exception e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        }

        String returnMessage = null;
        // GxIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    public String deleteAdExtensionsFromCampaigns(long customerAccountId, String adExtensionIdToCampaignIdAssociationsXML) {
        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        //DeleteAdExtensionsFromCampaignsRequest deleteAdExtensionsFromCampaignsRequest = null;
        DeleteAdExtensionsAssociationsRequest deleteAdExtensionsFromCampaignsRequest = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        //AdExtensionIdToCampaignIdAssociation[] adExtensionIdToCampaignIdAssociations = null;
        AdExtensionIdToEntityIdAssociation[] adExtensionIdToCampaignIdAssociations = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            deleteAdExtensionsFromCampaignsRequest = new DeleteAdExtensionsAssociationsRequest();
            deleteAdExtensionsFromCampaignsRequest.setAccountId(customerAccountId);
            // Parse adExtensionIdToCampaignIdAssociations from XML
            adExtensionIdToCampaignIdAssociations = util.adExtensionIdToCampaignIdAssociationsFromXML(adExtensionIdToCampaignIdAssociationsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            deleteAdExtensionsFromCampaignsRequest.setAdExtensionIdToEntityIdAssociations(adExtensionIdToCampaignIdAssociations);

            // Call WS
            //campaignManagement.deleteAdExtensionsFromCampaigns(deleteAdExtensionsFromCampaignsRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail
            campaignManagement.deleteAdExtensionsAssociations(deleteAdExtensionsFromCampaignsRequest);

            // Call succeeded with no errors

            // Create the return object

            //result = new GxAdExtensionIdCampaignIdResults(trackingId, adExtensionIdToCampaignIdAssociations.length);
            for (int i=0; i<adExtensionIdToCampaignIdAssociations.length; i++) {
                GA_ResultItem resultItem =  new GA_ResultItem();
                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxCampaignId();
                resultItem.AdExtensionId = ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId();
                resultItem.CampaignId =  adExtensionIdToCampaignIdAssociations[i].getEntityId();

                result.Items.add(resultItem);
                //result.addResult(i, new GxAdExtensionIdCampaignIdResult(((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxAdExtensionId(), ((GxAdExtensionIdToCampaignIdAssociation) adExtensionIdToCampaignIdAssociations[i]).getGxCampaignId(), adExtensionIdToCampaignIdAssociations[i].getAdExtensionId(), adExtensionIdToCampaignIdAssociations[i].getEntityId()));
            }
        } catch (GxException e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        } catch (ApiFaultDetail fault) { // IN CALL
            for (int i=0; i<deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault, i);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(fault);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem(e);

                resultItem.AdExtensionGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxAdExtensionId();
                resultItem.SubCampaignGxId = ((GxAdExtensionIdToCampaignIdAssociation) deleteAdExtensionsFromCampaignsRequest.getAdExtensionIdToEntityIdAssociations()[i]).getGxCampaignId();

                result.Items.add(resultItem);
            }
        } catch (Exception e) { // BEFORE CALL
            result.Items.add(new GA_ResultItem(e));
        }

        String returnMessage = null;
        // GxAdExtensionIdCampaignIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }
}
